﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Animation;

namespace G.Animation.PathAnimation
{
    public class PointAnimationUsingPath : BaseAnimationUsingPath
    {
        public override void CreateStory()
        {
            if (!IsStoryDirty)
                return;

            if (Duration == null ||
                Target == null ||
                TargetProperty == null ||
                PathGeometry == null ||
                PathGeometry is GeometryGroup) // won't work with GeometryGroups!
            {
                Story = null;
                return;
            }

            Story = new Storyboard();
            Story.BeginTime = BeginTime;
            Story.Duration = Duration;
            Story.AutoReverse = AutoReverse;
            Story.FillBehavior = FillBehavior;
            Story.RepeatBehavior = RepeatBehavior;

            Story.Completed += delegate(object sender, EventArgs e) { OnCompleted(e); };

            Storyboard.SetTarget(Story, Target);
            Storyboard.SetTargetProperty(Story, TargetProperty);

            PathGeometryHelper helper = new PathGeometryHelper();
            PathGeometry flattenedGeometry = helper.FlattenGeometry(PathGeometry, Tolerance);

            double length;

            List<Point> points = GetPointsOnFlattenedPath(flattenedGeometry, out length);

            PointAnimationUsingKeyFrames keyFrames = new PointAnimationUsingKeyFrames();

            // handle first keyframe 
            LinearPointKeyFrame keyFrameZero = new LinearPointKeyFrame();
            keyFrameZero.KeyTime = TimeSpan.Zero;
            keyFrameZero.Value = points[0];

            keyFrames.KeyFrames.Add(keyFrameZero);

            double accumLength = 0;

            for (int i = 0; i < points.Count - 1; i++)
            {
                accumLength += CalculateDistance(points[i], points[i + 1]);
                double fractionOfOverAllLength = accumLength / length;

                LinearPointKeyFrame keyFrame = new LinearPointKeyFrame();

                keyFrame.KeyTime = new TimeSpan(0, 0, 0, 0, (int)(Duration.TotalMilliseconds * fractionOfOverAllLength));

                keyFrame.Value = points[i + 1];

                keyFrames.KeyFrames.Add(keyFrame);
            }

            Story.Children.Add(keyFrames);

            IsStoryDirty = false;
        }
    }
}
